using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Collections.Generic;
using OpiConsole;

namespace Example
{
    public class Example : Microsoft.Xna.Framework.Game
    {
        public GraphicsDeviceManager graphics
        {
            get;
            set;
        }
        SpriteBatch spriteBatch;

        //Console
        OpiConsole.Console console;

        //Game Variables
        public Texture2D m_tBlankTexture;
        public List<RectangleSprite> m_lRectangles;
        bool bDefaultFont = true;
        bool bDefaultColour = true;
        bool bDefaultTextBox = true;
        KeyboardState lastKeyboardState;
        GamePadState lastGamePadState;

        public Example()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            //Create our console
            console = new OpiConsole.Console(this, spriteBatch, this);

            //Setup The Console
            console.Enabled = true;
            console.DrawConsole = true;
            console.RelayConsoleToVS = true;

            //Make sure we can see the debug too
            console.UserLevel = UsageLevel.DEBUGDEV;
        }

        protected override void Initialize()
        {
            //Setup Guide
            Components.Add(new GamerServicesComponent(this));

            //Add the Console as a component
            Components.Add(console);

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            //Create and register our commands
            console.RegisterCommand(new Command_Add());
            console.RegisterCommand(new Command_Sin());
            console.RegisterCommand(new Command_RemoveAllRectangles());
            console.RegisterCommand(new Command_RemoveRectangle());
            console.RegisterCommand(new Command_Retangle());
            console.RegisterCommand(new Command_ChangeResolution());

            //Create and register our cvars
            console.RegisterCVar(new CVar_Language());

            //Load Saved CVars
            console.LoadConfig();

            //Create our rectangles for our game
            m_tBlankTexture = Content.Load<Texture2D>("Materials/blank");
            m_lRectangles = new List<RectangleSprite>();
            m_lRectangles.Add(new RectangleSprite(50, 50, 25, 35, m_tBlankTexture));
            m_lRectangles.Add(new RectangleSprite(150, 150, 10, 100, m_tBlankTexture));

            //Print Info 
            console.Print("--- Buttons ---");
            console.Print("Oem8 (`) - Open/Close Console");
            console.Print("Mouse Wheel or Page Up/Down - Scroll the Console");
            console.Print("F1 or A Button - Change Font");
            console.Print("F2 or B Button - Change Text Colour");
            console.Print("F3 or X Button - Check what language is set, change it with the command 'cvar language'");
            console.Print("F4 or Y Button - Change Textbox Texture");
            console.Print("--- Commands ---");
            console.Print("createRectangle - Create a rectangle which is drawn to the screen.");
            console.Print("removeRectangle - Remove one rectangle from the screen.");
            console.Print("removeAllRectangles - Remove all rectangles from the screen.");

            //Update Keyboard/Gamepad State
            lastKeyboardState = Keyboard.GetState();
            lastGamePadState = GamePad.GetState(PlayerIndex.One);
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed 
                && lastGamePadState.Buttons.A == ButtonState.Released ||
 
                Keyboard.GetState().IsKeyDown(Keys.F1) && 
                lastKeyboardState.IsKeyUp(Keys.F1))

            {
                //Change the font
                if (bDefaultFont)
                {
                    console.Font = Content.Load<SpriteFont>("Materials/Fonts/Consolas_16pt");
                    bDefaultFont = !bDefaultFont;
                }
                else
                {
                    //Setting the font to null will load the default font
                    console.Font = null;
                    bDefaultFont = !bDefaultFont;
                }
            }

            if (GamePad.GetState(PlayerIndex.One).Buttons.B == ButtonState.Pressed
                    && lastGamePadState.Buttons.B == ButtonState.Released ||

                    Keyboard.GetState().IsKeyDown(Keys.F2) &&
                    lastKeyboardState.IsKeyUp(Keys.F2))
            {
                //Change the background/text colours
                if (bDefaultColour)
                {
                    console.BackgroundColour = new Color(255,255,255,200);
                    console.SetTextColour(new Color(18, 150, 134), ConsoleLevel.DEBUG);
                    console.SetTextColour(new Color(25, 87, 62), ConsoleLevel.NORM);
                    console.SetTextColour(new Color(164, 171, 82), ConsoleLevel.WARN);
                    bDefaultColour = !bDefaultColour;
                }
                else
                {
                    console.BackgroundColour = new Color(0,0,0,100);
                    console.SetTextColour(new Color(128, 128, 128), ConsoleLevel.DEBUG);
                    console.SetTextColour(new Color(255, 255, 255), ConsoleLevel.NORM);
                    console.SetTextColour(new Color(255, 255, 0), ConsoleLevel.WARN);

                    bDefaultColour = !bDefaultColour;
                }
            }

            //Show which language is currently set
            if (GamePad.GetState(PlayerIndex.One).Buttons.X == ButtonState.Pressed
                && lastGamePadState.Buttons.X == ButtonState.Released ||

                Keyboard.GetState().IsKeyDown(Keys.F3) &&
                lastKeyboardState.IsKeyUp(Keys.F3))
            {
                if (console.GetCVar("language").ToString().ToLower() == "english")
                {
                    console.Print("Language is currently: " + console.GetCVar("language").ToString());
                }
                else if (console.GetCVar("language").ToString().ToLower() == "german")
                {
                    console.Print("Language is currently: " + console.GetCVar("language").ToString());
                }
                else
                {
                    console.Print("Unrecognized language.", ConsoleLevel.FAIL);
                }
            }

            if (GamePad.GetState(PlayerIndex.One).Buttons.Y == ButtonState.Pressed
                    && lastGamePadState.Buttons.Y == ButtonState.Released ||

                    Keyboard.GetState().IsKeyDown(Keys.F4) &&
                    lastKeyboardState.IsKeyUp(Keys.F4))
            {
                //Change the font
                if (bDefaultTextBox)
                {
                    console.TextboxTexture = Content.Load<Texture2D>("Materials/textbox_red");
                    bDefaultTextBox = !bDefaultTextBox;
                }
                else
                {
                    //Setting the TextboxTexture to null will load the default texture
                    console.TextboxTexture = null;
                    bDefaultTextBox = !bDefaultTextBox;
                }
            }

            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            //Update Keyboard/Gamepad State
            lastKeyboardState = Keyboard.GetState();
            lastGamePadState = GamePad.GetState(PlayerIndex.One);

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            //Draw our rectangles
            spriteBatch.Begin();
            foreach (RectangleSprite r in m_lRectangles)
            {
                r.DrawElement(gameTime,spriteBatch);
            }
            spriteBatch.End();

            base.Draw(gameTime);
        }

        protected override void OnExiting(object sender, System.EventArgs args)
        {
            //Save the CVars on exit
            console.SaveConfig();

            base.OnExiting(sender, args);
        }
    }
}
